

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>Ceph MDS Locker &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../../../_static/favicon.ico"/>
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/underscore.js"></script>
        <script src="../../../_static/doctools.js"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../genindex/" />
    <link rel="search" title="Search" href="../../../search/" />
    <link rel="next" title="RADOS 网关开发者文档" href="../../radosgw/" />
    <link rel="prev" title="Subtree exports" href="../exports/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../../" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../../internals/">Ceph 内幕</a> &raquo;</li>
        
          <li><a href="../">MDS 开发者文档</a> &raquo;</li>
        
      <li>Ceph MDS Locker</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
          
            <a href="../../../_sources/dev/mds_internals/locking.rst.txt" rel="nofollow"> View page source</a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../../">
          

          
            
            <img src="../../../_static/logo.png" class="logo" alt="Logo"/>
          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../start/intro/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../developer_guide/">开发者指南</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../internals/">Ceph 内幕</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../blkin/">Tracing Ceph With LTTng</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../blkin/#tracing-ceph-with-blkin">Tracing Ceph With Blkin</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../bluestore/">BlueStore Internals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cache-pool/">Cache pool</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../ceph_krb_auth/">如何配置好 Ceph Kerberos 认证的详细文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephfs-mirroring/">CephFS Mirroring</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephfs-reclaim/">CephFS Reclaim Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephfs-snapshots/">CephFS 快照</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephx/">Cephx</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephx_protocol/">Cephx 认证协议详细阐述</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../config/">配置管理系统</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../config-key/">config-key layout</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../context/">CephContext</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../continuous-integration/">Continuous Integration Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../corpus/">资料库结构</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cpu-profiler/">Oprofile 的安装</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cxx/">C++17 and libstdc++ ABI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../deduplication/">去重</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../delayed-delete/">CephFS delayed deletion</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev_cluster_deployement/">开发集群的部署</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev_cluster_deployement/#id5">在同一机器上部署多套开发集群</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../development-workflow/">开发流程</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../documenting/">为 Ceph 写作文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../encoding/">序列化（编码、解码）</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../erasure-coded-pool/">纠删码存储池</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../file-striping/">File striping</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../freebsd/">FreeBSD Implementation details</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../generatedocs/">Ceph 文档的构建</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../health-reports/">Health Reports</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../iana/">IANA 号</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../kubernetes/">Hacking on Ceph in Kubernetes with Rook</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../libs/">库体系结构</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../logging/">集群日志的用法</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../logs/">调试日志</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../macos/">在 MacOS 上构建</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../messenger/">Messenger notes</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../mon-bootstrap/">Monitor bootstrap</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../mon-elections/">Monitor Elections</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../mon-on-disk-formats/">ON-DISK FORMAT</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../mon-osdmap-prune/">FULL OSDMAP VERSION PRUNING</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../msgr2/">msgr2 协议（ msgr2.0 和 msgr2.1 ）</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../network-encoding/">Network Encoding</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../network-protocol/">网络协议</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../object-store/">对象存储架构概述</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../osd-class-path/">OSD class path issues</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../peering/">互联</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../perf/">Using perf</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../perf_counters/">性能计数器</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../perf_histograms/">Perf histograms</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../placement-group/">PG （归置组）说明</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../quick_guide/">开发者指南（快速）</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../rados-client-protocol/">RADOS 客户端协议</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../rbd-diff/">RBD 增量备份</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../rbd-export/">RBD Export &amp; Import</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../rbd-layering/">RBD Layering</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../release-checklists/">Release checklists</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../release-process/">Ceph Release Process</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../seastore/">SeaStore</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../sepia/">Sepia 社区测试实验室</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../session_authentication/">Session Authentication for the Cephx Protocol</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../testing/">测试笔记</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../versions/">Public OSD Version</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../vstart-ganesha/">NFS CephFS-RGW Developer Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../wireshark/">Wireshark Dissector</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../zoned-storage/">Zoned Storage Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../osd_internals/">OSD 开发者文档</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../">MDS 开发者文档</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../data-structures/">MDS 内部数据结构</a></li>
<li class="toctree-l3"><a class="reference internal" href="../exports/">Subtree exports</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Ceph MDS Locker</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#why-use-locks">Why use locks?</a></li>
<li class="toctree-l4"><a class="reference internal" href="#lock-types">Lock Types</a></li>
<li class="toctree-l4"><a class="reference internal" href="#lock-classes">Lock Classes</a></li>
<li class="toctree-l4"><a class="reference internal" href="#read-write-and-exclusive-locks">Read, Write and Exclusive Locks</a></li>
<li class="toctree-l4"><a class="reference internal" href="#lock-states-and-lock-state-machine">Lock States and Lock State Machine</a></li>
<li class="toctree-l4"><a class="reference internal" href="#lock-transition">Lock Transition</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../radosgw/">RADOS 网关开发者文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../ceph-volume/">ceph-volume 开发者文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../crimson/">Crimson developer documentation</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <div class="section" id="ceph-mds-locker">
<h1>Ceph MDS Locker<a class="headerlink" href="#ceph-mds-locker" title="Permalink to this headline">¶</a></h1>
<div class="section" id="why-use-locks">
<h2>Why use locks?<a class="headerlink" href="#why-use-locks" title="Permalink to this headline">¶</a></h2>
<p>Locking infrastructure in MDS is (obviously) to protect the state of various metadata. MDS has different locks covering different portions of inode and dentry. Moreover, MDS uses different kinds of locks since different metadata (in inode and dentry) have different behaviour in different situations. The MDS cache is distributed across multiple MDS ranks and across all clients. The locking infrastructure serves to ensure that all ranks and clients are consistent in their view of the file system.</p>
<p>Data managed by the MDS can be very large to practically have the entire data set in the memory of a single metadata server. This also results in a single point of failure. The MDS therefore has a concept of Distributed Subtree Partition. A directory tree can be divided into smaller sub-trees. This is done by recording heat (access frequency) of each node in the directory tree. When a sub-tree heat reaches a configured threshold, the MDS divides the sub-tree by splitting the directory fragment. Each fragment is responsible for a part of the original directory, however, there will be a single authority node for these fragments. Each MDS can bear the read and write requests after fragmentation. If a file is very frequently accessed, the MDS will generate multiple copies distributed across active MDSs to satisfy concurrent I/Os. Typically, there are multiple clients reading and writing to files. The MDS defines locking rules for the associated metadata, e.g., metadata which is rarely modified concurrently such as UID/GID for an inode, a shared read and exclusive write access rule would suffice. However, statistics of a directory may need to be updated by multiple clients at the same time. This large directory may have been divided (fragmented) into multiple shards and different clients could write to different shards. These shards can share the read and also support simultaneous writes.</p>
<p>Therefore, in addition to different lock types that cover different metadata pieces for an inode, the MDS has lock classes that define access rules for a particular lock type. Lock types and classes are explained further in this document.</p>
</div>
<div class="section" id="lock-types">
<h2>Lock Types<a class="headerlink" href="#lock-types" title="Permalink to this headline">¶</a></h2>
<p>MDS defines a handful of lock types associated with different metadata for an inode or dentry. Lock type protecting metadata for an inode and dentry are as follows:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CEPH_LOCK_DN</span>       <span class="o">-</span> <span class="n">dentry</span>
<span class="n">CEPH_LOCK_DVERSION</span> <span class="o">-</span> <span class="n">dentry</span> <span class="n">version</span>
<span class="n">CEPH_LOCK_IVERSION</span> <span class="o">-</span> <span class="n">inode</span> <span class="n">version</span>
<span class="n">CEPH_LOCK_IAUTH</span>    <span class="o">-</span> <span class="n">mode</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span>
<span class="n">CEPH_LOCK_ILINK</span>    <span class="o">-</span> <span class="n">nlink</span>
<span class="n">CEPH_LOCK_IDFT</span>     <span class="o">-</span> <span class="n">dirfragtree</span><span class="p">,</span> <span class="n">frags</span>
<span class="n">CEPH_LOCK_IFILE</span>    <span class="o">-</span> <span class="n">mtime</span><span class="p">,</span> <span class="n">atime</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">truncate_seq</span><span class="p">,</span> <span class="n">truncate_size</span><span class="p">,</span> <span class="n">client_ranges</span><span class="p">,</span> <span class="n">inline_data</span>
<span class="n">CEPH_LOCK_INEST</span>    <span class="o">-</span> <span class="n">rstats</span>
<span class="n">CEPH_LOCK_IXATTR</span>   <span class="o">-</span> <span class="n">xattrs</span>
<span class="n">CEPH_LOCK_ISNAP</span>    <span class="o">-</span> <span class="n">snaps</span>
<span class="n">CEPH_LOCK_IFLOCK</span>   <span class="o">-</span> <span class="n">file</span> <span class="n">locks</span>
<span class="n">CEPH_LOCK_IPOLICY</span>  <span class="o">-</span> <span class="n">layout</span><span class="p">,</span> <span class="n">quota</span><span class="p">,</span> <span class="n">export_pin</span><span class="p">,</span> <span class="n">ephemeral_</span><span class="o">*</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Locking rules when modifying <cite>ctime</cite> is a bit different - either under <cite>versionlock</cite> or under no specific lock at all (i.e., it can be modified with other locks held, e.g., when modifying (say) uid/gid under <cite>CEPH_LOCK_IAUTH</cite>).</p>
</div>
</div>
<div class="section" id="lock-classes">
<h2>Lock Classes<a class="headerlink" href="#lock-classes" title="Permalink to this headline">¶</a></h2>
<p>Lock classes define locking behaviour for the associated lock type necessary for handling distributed locks. The MDS defines 3 lock classes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">LocalLock</span>   <span class="o">-</span> <span class="n">Used</span> <span class="k">for</span> <span class="n">data</span> <span class="n">that</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">require</span> <span class="n">distributed</span> <span class="n">locking</span> <span class="n">such</span> <span class="k">as</span> <span class="n">inode</span> <span class="ow">or</span> <span class="n">dentry</span> <span class="n">version</span> <span class="n">information</span><span class="o">.</span> <span class="n">Local</span> <span class="n">locks</span> <span class="n">are</span> <span class="n">versioned</span> <span class="n">locks</span><span class="o">.</span>

<span class="n">SimpleLock</span>  <span class="o">-</span> <span class="n">Used</span> <span class="k">for</span> <span class="n">data</span> <span class="n">that</span> <span class="n">requires</span> <span class="n">shared</span> <span class="n">read</span> <span class="ow">and</span> <span class="n">mutually</span> <span class="n">exclusive</span> <span class="n">write</span><span class="o">.</span> <span class="n">This</span> <span class="n">lock</span> <span class="k">class</span> <span class="nc">is</span> <span class="n">also</span> <span class="n">the</span> <span class="n">base</span> <span class="k">class</span> <span class="nc">for</span> <span class="n">other</span> <span class="n">lock</span> <span class="n">classes</span> <span class="ow">and</span> <span class="n">specifies</span> <span class="n">most</span> <span class="n">of</span> <span class="n">the</span> <span class="n">locking</span> <span class="n">behaviour</span> <span class="k">for</span> <span class="n">implementing</span> <span class="n">distributed</span> <span class="n">locks</span><span class="o">.</span>

<span class="n">ScatterLock</span> <span class="o">-</span> <span class="n">Used</span> <span class="k">for</span> <span class="n">data</span> <span class="n">that</span> <span class="n">requires</span> <span class="n">shared</span> <span class="n">read</span> <span class="ow">and</span> <span class="n">shared</span> <span class="n">write</span><span class="o">.</span> <span class="n">Typical</span> <span class="n">use</span> <span class="ow">is</span> <span class="n">where</span> <span class="n">an</span> <span class="n">MDS</span> <span class="n">can</span> <span class="n">delegate</span> <span class="n">some</span> <span class="n">authority</span> <span class="n">to</span> <span class="n">other</span> <span class="n">MDS</span> <span class="n">replicas</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">g</span><span class="o">.</span><span class="p">,</span> <span class="n">replica</span> <span class="n">MDSs</span> <span class="n">can</span> <span class="n">satisfy</span> <span class="n">read</span> <span class="n">capablities</span> <span class="k">for</span> <span class="n">clients</span><span class="o">.</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>In addition, MDS defines FileLock which is a special case of ScatterLock used for data that requires shared read and shared write, but also for protecting other peices of metadata that require shared read and mutually exclusive write.</p>
</div>
<p>Classification of lock types are as follows:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">SimpleLock</span>
  <span class="n">CEPH_LOCK_DN</span>
  <span class="n">CEPH_LOCK_IAUTH</span>
  <span class="n">CEPH_LOCK_ILINK</span>
  <span class="n">CEPH_LOCK_IXATTR</span>
  <span class="n">CEPH_LOCK_ISNAP</span>
  <span class="n">CEPH_LOCK_IFLOCK</span>
  <span class="n">CEPH_LOCK_IPOLICY</span>

<span class="n">ScatterLock</span>
  <span class="n">CEPH_LOCK_INEST</span>
  <span class="n">CEPH_LOCK_IDFT</span>

<span class="n">FileLock</span>
  <span class="n">CEPH_LOCK_IFILE</span>

<span class="n">LocalLock</span>
  <span class="n">CEPH_LOCK_DVERSION</span>
  <span class="n">CEPH_LOCK_IVERSION</span>
</pre></div>
</div>
</div>
<div class="section" id="read-write-and-exclusive-locks">
<h2>Read, Write and Exclusive Locks<a class="headerlink" href="#read-write-and-exclusive-locks" title="Permalink to this headline">¶</a></h2>
<p>There are 3 modes in which a lock can be acquired:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rdlock</span> <span class="o">-</span> <span class="n">shared</span> <span class="n">read</span> <span class="n">lock</span>
<span class="n">wrlock</span> <span class="o">-</span> <span class="n">shared</span> <span class="n">write</span> <span class="n">lock</span>
<span class="n">xlock</span>  <span class="o">-</span> <span class="n">exclusive</span> <span class="n">lock</span>
</pre></div>
</div>
<p><cite>rdlock</cite> and <cite>xlock</cite> are self explanatory.</p>
<p><cite>wrlock</cite> is special since it allows concurrent writers and is valid for <cite>ScatterLock</cite> and <cite>FileLock</cite> class. From the earlier section it can be seen that <cite>INEST</cite> and <cite>IDFT</cite> are of <cite>ScatterLock</cite> class. <cite>wrlock</cite> allows multiple writers at the same time, .e.g., when a (large) directory is split into multiple shards (after fragmentation) and each shard is “assigned” to an active MDS. When new files are created under these directories, the recursive stats are independently updated on the active MDSs. Later, to fetch the updated stats, the “scattered” data is aggregated (“gathered”) on the auth MDS (of the inode); which typically happens when a <cite>rdlock</cite> is requested on this lock type.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>MDS also defines <cite>remote_wrlock</cite> which is primarly used during rename operation when the destination dentry is on another (active) MDS than the source MDS.</p>
</div>
</div>
<div class="section" id="lock-states-and-lock-state-machine">
<h2>Lock States and Lock State Machine<a class="headerlink" href="#lock-states-and-lock-state-machine" title="Permalink to this headline">¶</a></h2>
<p>MDS defines various lock states (defined in <cite>src/mds/locks.h</cite> source). Not all lock states are valid for a given lock class. Each lock class defines its own lock transition rules and are organized as Lock State Machines. The lock states (<cite>LOCK_*</cite>) are not locks themselves, but control if a lock is allowed to be taken. Each state follows <cite>LOCK_&lt;STATE&gt;</cite> or <cite>LOCK_&lt;FROM_STATE&gt;_&lt;TO_STATE&gt;</cite> naming terminology and can be summed up as:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">LOCK_SYNC</span>  <span class="o">-</span> <span class="n">anybody</span> <span class="p">(</span><span class="n">ANY</span><span class="p">)</span> <span class="n">can</span> <span class="n">read</span> <span class="n">lock</span><span class="p">,</span> <span class="n">no</span> <span class="n">one</span> <span class="n">can</span> <span class="n">write</span> <span class="n">lock</span> <span class="ow">and</span> <span class="n">exclusive</span> <span class="n">lock</span>
<span class="n">LOCK_LOCK</span>  <span class="o">-</span> <span class="n">no</span> <span class="n">one</span> <span class="n">can</span> <span class="n">read</span> <span class="n">lock</span><span class="p">,</span> <span class="n">only</span> <span class="n">primary</span> <span class="p">(</span><span class="n">AUTH</span><span class="p">)</span> <span class="n">mds</span> <span class="n">can</span> <span class="n">write</span> <span class="n">lock</span> <span class="ow">or</span> <span class="n">exclusive</span> <span class="n">lock</span>
<span class="n">LOCK_MIX</span>   <span class="o">-</span> <span class="n">anybody</span> <span class="p">(</span><span class="n">ANY</span><span class="p">)</span> <span class="n">can</span> <span class="n">write</span> <span class="n">lock</span><span class="p">,</span> <span class="n">no</span> <span class="n">one</span> <span class="n">can</span> <span class="n">read</span> <span class="n">lock</span> <span class="ow">or</span> <span class="n">exclusive</span> <span class="n">lock</span>
<span class="n">LOCK_XLOCK</span> <span class="o">-</span> <span class="n">someone</span> <span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="ow">is</span> <span class="n">holding</span> <span class="n">a</span> <span class="n">exclusive</span> <span class="n">lock</span>
</pre></div>
</div>
<p>The Lock Transition table (section) use the following notions:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ANY</span>  <span class="o">-</span> <span class="n">Auth</span> <span class="ow">or</span> <span class="n">Replica</span> <span class="n">MDS</span>
<span class="n">AUTH</span> <span class="o">-</span> <span class="n">Auth</span> <span class="n">MDS</span>
<span class="n">XCL</span>  <span class="o">-</span> <span class="n">Auth</span> <span class="n">MDS</span> <span class="ow">or</span> <span class="n">Exclusive</span> <span class="n">client</span>
</pre></div>
</div>
<p>Other lock states (such as <cite>LOCK_XSYN</cite>, <cite>LOCK_TSYN</cite>, etc..) are additional states that are defined as an optimization for certain client behaviour (<cite>LOCK_XSYN</cite> allows clients to keep the buffered writes and not flush it to the OSDs and temporarily pausing writes).</p>
<p>Intermediate lock states (<cite>LOCK_&lt;FROM_STATE&gt;_&lt;TO_STATE&gt;</cite>) denote transition of a lock from one state (<cite>&lt;FROM_STATE&gt;</cite>) to another (<cite>&lt;TO_STATE&gt;</cite>).</p>
<p>Each lock class defines its own Lock State Machine and can be found in <cite>src/mds/locks.c</cite> source. The state machines are explained when discussing Lock Transition in the section below.</p>
</div>
<div class="section" id="lock-transition">
<h2>Lock Transition<a class="headerlink" href="#lock-transition" title="Permalink to this headline">¶</a></h2>
<p>Transition of lock from one state to another is mostly prompted by a (client) request or a change that the MDS is undergoing, such as tree migration. Let’s consider a simple case of two clients: One client does a <cite>stat()</cite> (<cite>getattr()</cite> or <cite>lookup()</cite>) to fetch UID/GID of a inode, and the other client does a <cite>setattr()</cite> to change the UID/GID of the same inode. The first client (most likely) has <cite>As</cite> (iauth shared) caps issued to it by the MDS. Now, when the other client does a <cite>setattr()</cite> call to the MDS, the MDS adds a <cite>xlock</cite> to the inodes’ <cite>authlock</cite> (<cite>CEPH_LOCK_IAUTH</cite>):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Server</span><span class="p">::</span><span class="n">handle_client_setattr</span><span class="p">()</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">mask</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">CEPH_SETATTR_MODE</span><span class="o">|</span><span class="n">CEPH_SETATTR_UID</span><span class="o">|</span><span class="n">CEPH_SETATTR_GID</span><span class="o">|</span><span class="n">CEPH_SETATTR_BTIME</span><span class="o">|</span><span class="n">CEPH_SETATTR_KILL_SGUID</span><span class="p">))</span>
      <span class="n">lov</span><span class="o">.</span><span class="n">add_xlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">cur</span><span class="o">-&gt;</span><span class="n">authlock</span><span class="p">);</span>
</pre></div>
</div>
<p>Note that the MDS adds a bunch of other locks for this inode, but for now let’s only work on IAUTH. Now, <cite>CEPH_LOCK_IAUTH</cite> is a <cite>SimpleLock</cite> class, and its lock transition state machine is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>                  <span class="o">//</span> <span class="n">stable</span>     <span class="n">loner</span>  <span class="n">rep</span> <span class="n">state</span>  <span class="n">r</span>     <span class="n">rp</span>   <span class="n">rd</span>   <span class="n">wr</span>   <span class="n">fwr</span>  <span class="n">l</span>    <span class="n">x</span>    <span class="n">caps</span><span class="p">,</span><span class="n">other</span>
<span class="p">[</span><span class="n">LOCK_SYNC</span><span class="p">]</span>      <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span>         <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">ANY</span><span class="p">,</span>  <span class="mi">0</span><span class="p">,</span>   <span class="n">ANY</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">ANY</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">CEPH_CAP_GSHARED</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_LOCK_SYNC</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">AUTH</span><span class="p">,</span> <span class="n">XCL</span><span class="p">,</span> <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_EXCL_SYNC</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">true</span><span class="p">,</span>  <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_SNAP_SYNC</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">AUTH</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>

<span class="p">[</span><span class="n">LOCK_LOCK</span><span class="p">]</span>      <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span>         <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">AUTH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="n">REQ</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_SYNC_LOCK</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">ANY</span><span class="p">,</span>  <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_EXCL_LOCK</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>

<span class="p">[</span><span class="n">LOCK_PREXLOCK</span><span class="p">]</span>  <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">ANY</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_XLOCK</span><span class="p">]</span>     <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_XLOCKDONE</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_SYNC</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">XCL</span><span class="p">,</span>  <span class="n">XCL</span><span class="p">,</span> <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_LOCK_XLOCK</span><span class="p">]</span><span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_PREXLOCK</span><span class="p">,</span><span class="n">false</span><span class="p">,</span><span class="n">LOCK_LOCK</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>

<span class="p">[</span><span class="n">LOCK_EXCL</span><span class="p">]</span>      <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span>         <span class="n">true</span><span class="p">,</span>  <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="mi">0</span><span class="p">,</span>   <span class="n">REQ</span><span class="p">,</span> <span class="n">XCL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="n">CEPH_CAP_GEXCL</span><span class="o">|</span><span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_SYNC_EXCL</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_EXCL</span><span class="p">,</span> <span class="n">true</span><span class="p">,</span>  <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">ANY</span><span class="p">,</span>  <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
<span class="p">[</span><span class="n">LOCK_LOCK_EXCL</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">LOCK_EXCL</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">AUTH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="n">CEPH_CAP_GSHARED</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>

<span class="p">[</span><span class="n">LOCK_REMOTEXLOCK</span><span class="p">]</span><span class="o">=</span><span class="p">{</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="n">false</span><span class="p">,</span> <span class="n">LOCK_LOCK</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>    <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span> <span class="p">},</span>
</pre></div>
</div>
<p>The state transition entries are of type <cite>sm_state_t</cite> from <cite>src/mds/locks.h</cite> source. TODO: Describe these in detail.</p>
<p>We reach a point where the MDS fills in <cite>LockOpVec</cite> and invokes <cite>Locker::acquire_locks()</cite>, which according to the lock type and the mode (<cite>rdlock</cite>, etc..) tries to acquire that particular lock. Starting state for the lock is <cite>LOCK_SYNC</cite> (this may not always be the case, but consider this for simplicity). To acquire <cite>xlock</cite> for <cite>iauth</cite>, the MDS refers to the state transition table. If the current state allows the lock to be acquired, the MDS grabs the lock (which is just incrementing a counter). The current state (<cite>LOCK_SYNC</cite>) does not allow <cite>xlock</cite> to be acquired (column <cite>x</cite> in <cite>LOCK_SYNC</cite> state), thereby requiring a lock state switch. At this point, the MDS switches to an intermediate state <cite>LOCK_SYNC_LOCK</cite> - signifying transitioning from <cite>LOCK_SYNC</cite> to <cite>LOCK_LOCK</cite> state. The intermediate state has a couple of purposes - a. The intermediate state defines what caps are allowed to be held by cilents thereby revoking caps that are not allowed be held in this state, and b. preventing new locks to be acquired. At this point the MDS sends cap revoke messages to clients:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2021</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">22</span><span class="n">T07</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mf">20.040</span><span class="o">-</span><span class="mi">0500</span> <span class="mi">7</span><span class="n">fa66a3bd700</span>  <span class="mi">7</span> <span class="n">mds</span><span class="mf">.0</span><span class="o">.</span><span class="n">locker</span><span class="p">:</span> <span class="n">issue_caps</span> <span class="n">allowed</span><span class="o">=</span><span class="n">pLsXsFscrl</span><span class="p">,</span> <span class="n">xlocker</span> <span class="n">allowed</span><span class="o">=</span><span class="n">pLsXsFscrl</span> <span class="n">on</span> <span class="p">[</span><span class="n">inode</span> <span class="mh">0x10000000003</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="n">head</span><span class="p">]</span> <span class="o">/</span><span class="n">testfile</span> <span class="n">auth</span> <span class="n">v142</span> <span class="n">ap</span><span class="o">=</span><span class="mi">1</span> <span class="n">DIRTYPARENT</span> <span class="n">s</span><span class="o">=</span><span class="mi">0</span> <span class="n">n</span><span class="p">(</span><span class="n">v0</span> <span class="n">rc2021</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">22</span><span class="n">T06</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mf">45.015746</span><span class="o">-</span><span class="mi">0500</span> <span class="mi">1</span><span class="o">=</span><span class="mi">1</span><span class="o">+</span><span class="mi">0</span><span class="p">)</span> <span class="p">(</span><span class="n">iauth</span> <span class="n">sync</span><span class="o">-&gt;</span><span class="n">lock</span><span class="p">)</span> <span class="p">(</span><span class="n">iversion</span> <span class="n">lock</span><span class="p">)</span> <span class="n">caps</span><span class="o">=</span><span class="p">{</span><span class="mi">94134</span><span class="o">=</span><span class="n">pAsLsXsFscr</span><span class="o">/-@</span><span class="mi">1</span><span class="p">,</span><span class="mi">94138</span><span class="o">=</span><span class="n">pLsXsFscr</span><span class="o">/-@</span><span class="mi">1</span><span class="p">}</span> <span class="o">|</span> <span class="n">request</span><span class="o">=</span><span class="mi">1</span> <span class="n">lock</span><span class="o">=</span><span class="mi">1</span> <span class="n">caps</span><span class="o">=</span><span class="mi">1</span> <span class="n">dirtyparent</span><span class="o">=</span><span class="mi">1</span> <span class="n">dirty</span><span class="o">=</span><span class="mi">1</span> <span class="n">authpin</span><span class="o">=</span><span class="mi">1</span> <span class="mh">0x5633ffdac000</span><span class="p">]</span>
<span class="mi">2021</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">22</span><span class="n">T07</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mf">20.040</span><span class="o">-</span><span class="mi">0500</span> <span class="mi">7</span><span class="n">fa66a3bd700</span> <span class="mi">20</span> <span class="n">mds</span><span class="mf">.0</span><span class="o">.</span><span class="n">locker</span><span class="p">:</span> <span class="n">client</span><span class="mf">.94134</span> <span class="n">pending</span> <span class="n">pAsLsXsFscr</span> <span class="n">allowed</span> <span class="n">pLsXsFscrl</span> <span class="n">wanted</span> <span class="o">-</span>
<span class="mi">2021</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">22</span><span class="n">T07</span><span class="p">:</span><span class="mi">18</span><span class="p">:</span><span class="mf">20.040</span><span class="o">-</span><span class="mi">0500</span> <span class="mi">7</span><span class="n">fa66a3bd700</span>  <span class="mi">7</span> <span class="n">mds</span><span class="mf">.0</span><span class="o">.</span><span class="n">locker</span><span class="p">:</span> <span class="n">sending</span> <span class="n">MClientCaps</span> <span class="n">to</span> <span class="n">client</span><span class="mf">.94134</span> <span class="n">seq</span> <span class="mi">2</span> <span class="n">new</span> <span class="n">pending</span> <span class="n">pLsXsFscr</span> <span class="n">was</span> <span class="n">pAsLsXsFscr</span>
</pre></div>
</div>
<p>As seen above, <cite>client.94134</cite> has <cite>As</cite> caps, which is getting revoked by the MDS. After the caps have been revoked, the MDS can continue to transition to further states: <cite>LOCK_SYNC_LOCK</cite> to <cite>LOCK_LOCK</cite>. Since the goal is to acquire <cite>xlock</cite>, the state transition conitnues (as per the lock transition state machine):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">LOCK_LOCK</span> <span class="o">-&gt;</span> <span class="n">LOCK_LOCK_XLOCK</span>
<span class="n">LOCK_LOCK_XLOCK</span> <span class="o">-&gt;</span> <span class="n">LOCK_PREXLOCK</span>
<span class="n">LOCK_PREXLOCK</span> <span class="o">-&gt;</span> <span class="n">LOCK_XLOCK</span>
</pre></div>
</div>
<p>finally, acquiring <cite>xlock</cite> on <cite>iauth</cite>.</p>
<p>TODO: Explain locking order and path traversal locking.</p>
</div>
</div>



           </div>
           
          </div>
          <footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
        <a href="../../radosgw/" class="btn btn-neutral float-right" title="RADOS 网关开发者文档" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
        <a href="../exports/" class="btn btn-neutral float-left" title="Subtree exports" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).

    </p>
  </div> 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>